package com.bigfans.framework.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import com.bigfans.framework.model.AbstractModel;

/**
 * 
 * @Title: 
 * @Description: 
 * @author lichong 
 * @date 2016年1月16日 下午12:54:44 
 * @version V1.0
 */
public class SimpleJdbcDAO extends BaseDAOImpl implements JdbcDAO{
	
	public static final String BEAN_NAME = "simpleJdbcDAO";

	public int insert(final String sql, final Object[] params) {
		return insert(sql,params,null);
	}
	
	@Override
	public int insert(final String sql, final Object[] params,final GeneratedKey generatedKey) {
		final KeyHolder keyHolder = new GeneratedKeyHolder();
	    getTx().execute(new TransactionCallback<Object>() {
			@Override
			public Object doInTransaction(TransactionStatus status) {
				return getJdbcTemplate().update(new PreparedStatementCreator() {
					public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
						PreparedStatement ps = con.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
						for (int i = 1;i<=params.length;i++) {
							ps.setObject(i, params[i-1]);
						}
						return ps;
					}
				}, keyHolder);
			}
		});
	    if(generatedKey != null){
	    	generatedKey.setKey(keyHolder.getKey());
	    }
		return 1;
	}
	
	public int batchInsert(final String sql , final Object[] params){
		getTx().execute(new TransactionCallback<Object>() {
			@Override
			public Object doInTransaction(TransactionStatus status) {
				return getJdbcTemplate().update(sql,params);
			}
		});
		return 0;
	}
	
	public int delete(final String sql , final Object[] params){
		getTx().execute(new TransactionCallback<Object>() {
			@Override
			public Object doInTransaction(TransactionStatus status) {
				return getJdbcTemplate().update(sql,params);
			}
		});
		return 0;
	}
	
	public int update(final String sql , final Object[] params){
		getTx().execute(new TransactionCallback<Object>() {
			@Override
			public Object doInTransaction(TransactionStatus status) {
				return getJdbcTemplate().update(sql,params);
			}
		});
		return 0;
	}
	
	public Long count(final String sql , final Object[] params){
		getTx().execute(new TransactionCallback<Long>() {
			@Override
			public Long doInTransaction(TransactionStatus status) {
				return getJdbcTemplate().queryForObject(sql , params , Long.class);
			}
		});
		return 0l;
	}
	
	public <M extends AbstractModel> M load(final Class<M> type ,final String sql ,final Object[] params ){
		final RowMapper<M> rm = BeanPropertyRowMapper.newInstance(type);
		M obj = getTx().execute(new TransactionCallback<M>() {
			@Override
			public M doInTransaction(TransactionStatus status) {
				return getJdbcTemplate().queryForObject(sql, params , rm);
			}
		});
		return obj;
	}
	
	public <M extends AbstractModel> List<M> list(final Class<M> type ,final String sql ,final Object[] params ){
		final RowMapper<M> rm = BeanPropertyRowMapper.newInstance(type);
		List<M> obj = getTx().execute(new TransactionCallback<List<M>>() {
			@Override
			public List<M> doInTransaction(TransactionStatus status) {
				return getJdbcTemplate().query(sql, params , rm);
			}
		});
		return obj;
	}
}
